import Vue from 'vue'
import axios from 'axios'

// create an axios instance
const service = axios.create({
  // baseURL: 'http://117.78.4.191:5151', // url = base url + request url
  baseURL: 'http://localhost:5151', // url = base url + request url
  //withCredentials: true, // send cookies when cross-domain requests 注意：withCredentials和后端配置的cross跨域不可同时使用
  timeout: 6000, // request timeout
  crossDomain: true
})
// token 键定义
export const accessTokenKey = "access-token";
export const refreshAccessTokenKey = `x-${accessTokenKey}`;
// request拦截器,在请求之前做一些处理
// service.interceptors.request.use(
//   config => {
//     // if (store.state.token) {
//     //     // 给请求头添加user-token
//     //     config.headers["user-token"] = store.state.token;
//     // }
//     console.log('请求拦截成功')
//     return config;
//   },
//   error => {
//     console.log(error); // for debug
//     return Promise.reject(error);
//   }
// );
// axios 请求拦截
service.interceptors.request.use(
  (conf) => {
    // 获取本地的 token
    const accessToken = uni.getStorageSync(accessTokenKey);
    if (accessToken) {
      // 将 token 添加到请求报文头中
      conf.headers["Authorization"] = `Bearer ${accessToken}`;

      // 判断 accessToken 是否过期
      // const jwt = decryptJWT(accessToken);
      // const exp = getJWTDate(jwt.exp);

      // // token 已经过期
      // if (new Date() >= exp) {
      //   // 获取刷新 token
      //   const refreshAccessToken = uni.getStorageSync(refreshAccessTokenKey);

      //   // 携带刷新 token
      //   if (refreshAccessToken) {
      //     conf.headers["X-Authorization"] = `Bearer ${refreshAccessToken}`;
      //   }
      // }
    }

    // 这里编写请求拦截代码 =========================================

    return conf;
  },
  (error) => {
    // 处理请求错误
    if (error.request) {
    }
    // 这里编写请求错误代码
    return Promise.reject(error);
  }
);


//配置成功后的拦截器
// service.interceptors.response.use(res => {
//   if (res.data.status == 200) {
//     return res.data
//   } else {
//     return Promise.reject(res.data.msg);
//   }
// }, error => {
//   if (error.response.status) {
//     switch (error.response.status) {
//       case 401:
//         break;
//       default:
//         break;
//     }
//   }
//   return Promise.reject(error)
// })
// axios 响应拦截
service.interceptors.response.use(
  (res) => {
    console.log("进入响应拦截");
    console.log(res);
    // 获取状态码和返回数据
    var status = res.status;
    var serve = res.data;

    // 处理 401
    if (status === 401) {
      clearAccessTokens();
    }

    // 处理未进行规范化处理的
    if (status >= 400) {
      throw new Error(res.statusText || "Request Error.");
    }
    console.log("进入处理规范化结果错误" + status);
    // 处理规范化结果错误
    if (serve
      && serve.hasOwnProperty("errors")
      && serve.errors) {
      throw new Error(JSON.stringify(serve.errors || "Request Error."));
    }
    // console.log("我要在这里改");
    // console.log(res.header);

    // 读取响应报文头 token 信息
    var accessToken = res.header[accessTokenKey];

    // var refreshAccessToken = res.headers[refreshAccessTokenKey];

    // 判断是否是无效 token
    if (accessToken === "invalid_token") {
      console.log("进入无效tokenAccess token");
      clearAccessTokens();
    }
    // 判断是否存在刷新 token，如果存在则存储在本地
    else if (
      // refreshAccessToken &&
      accessToken &&
      accessToken !== "invalid_token"
    ) {
      console.log("===============================");
      uni.setStorageSync(accessTokenKey, accessToken);
      // uni.setStorageSync(refreshAccessTokenKey, refreshAccessToken);
    }

    // 这里编写响应拦截代码 =========================================
    console.log("最后处理res");
    console.log(res);
    console.log("最后处理res");

    return res;
  },
  (error) => {
    // 处理响应错误
    if (error.response) {
      if (error.response.status === 401) {
        clearAccessTokens();
      }
    }

    // 这里编写响应错误代码
    console.log("进入了响应错误");
    return Promise.reject(error);
  }
);

// 在main.js中放入这段自定义适配器的代码，就可以实现uniapp的app和小程序开发中能使用axios进行跨域网络请求，并支持携带cookie
axios.defaults.adapter = function (config) {
  return new Promise((resolve, reject) => {
    console.log(config)
    var settle = require('axios/lib/core/settle');
    var buildURL = require('axios/lib/helpers/buildURL');
    uni.request({
      method: config.method.toUpperCase(),
      url: config.baseURL + buildURL(config.url, config.params, config.paramsSerializer),
      header: config.headers,
      data: config.data,
      dataType: config.dataType,
      responseType: config.responseType,
      sslVerify: config.sslVerify,
      complete: function complete (response) {
        console.log("执行完成：", response)
        response = {
          data: response.data,
          status: response.statusCode,
          errMsg: response.errMsg,
          header: response.header,
          config: config
        };

        settle(resolve, reject, response);
      }
    })
  }).catch(function (err) {
    console.error("在app.js中axios报错的" + e / rr);
    return reject(err);
  });
}



// 清除 token
const clearAccessTokens = () => {
  console.log("正在清空storage");
  uni.removeStorageSync(accessTokenKey);
  // uni.removeStorageSync(refreshAccessTokenKey);
  // 刷新浏览器
  // window.location.reload();

  // 这里可以添加清除更多 Key =========================================
};

/**
 * 包装 Promise 并返回 [Error, any]
 * @param promise Promise 方法
 * @param errorExt 自定义错误信息（拓展）
 * @returns [Error, any]
 */
export function feature (
  promise,
  errorExt
) {
  return promise
    .then((data) => [null, data])
    .catch((err) => {
      if (errorExt) {
        const parsedError = Object.assign({}, err, errorExt);
        return [parsedError, undefined];
      }

      return [err, undefined];
    });
}

/**
 * 解密 JWT token 的信息
 * @param token jwt token 字符串
 * @returns <any>object
 */
// export function decryptJWT (token) {
//   token = token.replace(/_/g, "/").replace(/-/g, "+");
//   console.log("token:" + uni.atob(token.split(".")[1]));

//   var json = decodeURIComponent(escape(uni.atob(token.split(".")[1])));
//   return JSON.parse(json);
// }

/**
 * 将 JWT 时间戳转换成 Date
 * @description 主要针对 `exp`，`iat`，`nbf`
 * @param timestamp 时间戳
 * @returns Date 对象
 */
// export function getJWTDate (timestamp) {
//   return new Date(timestamp * 1000);
// }
export default service